package com.dmx.cep.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.dmx.cep.entity.TvContentInfo;
import com.dmx.cep.entity.TvContentStatus;
import com.dmx.cep.service.EpgService;
import com.dmx.fw.resource.SystemProperties;
import com.dmx.fw.util.DateTimeUtils;

/**
 * EPG导入工具类
 * @author magicyang
 *
 */
public class EpgTextParse {
	
	Log log=LogFactory.getLog(EpgTextParse.class);
	
	/**
	 * EPG导入偏移时间量(分钟)
	 */
	public  int EPG_OFFSET_TIME=30;

	/**
	 * 导入节目最小时长(分钟)
	 */
	public  int PROGRAMME_MIN_DURATION=4;	
	
	/**
	 * 导入节目最大时长(分钟)
	 */
	public  int PROGRAMME_MAX_DURATION=3*60;
	
	
	private EpgService epgService;
	
	private InputStream xmlstream;
	
	private Reader xmlReader;
	
	private String channelCode;
	
	private List<TvContentInfo> tvContentList=new ArrayList<TvContentInfo>();
	
	private List<TvContentStatus> tvContentStatusList=new ArrayList<TvContentStatus>();
	
	private boolean errorFlag = false;
	
	private String errorCode;
	
	private String errorTime;
	
	/**
	 * 导入EPG节目单第一个节目的开始时间
	 */
	private Date programStartTime=null;
	
	public EpgTextParse(){}
	
	public EpgTextParse(InputStream _xmlstream,EpgService _epgService){
		this.xmlstream=_xmlstream;
		this.epgService=_epgService;
	}
	
	public EpgTextParse(Reader in,EpgService _epgService){
		this.xmlReader=in;
		this.epgService=_epgService;
	}
	
	public void parse(String language) throws Exception {
		
		SystemProperties systemProperties=SystemProperties.getInstance();
		try{
			EPG_OFFSET_TIME=Integer.parseInt(systemProperties.getPropertyVal("epg.import.offset.time"));
		}catch(Exception e){
			log.error(e);
		}
		
		try{
			PROGRAMME_MIN_DURATION=Integer.parseInt(systemProperties.getPropertyVal("epg.min.duration"));
		}catch(Exception e){
			log.error(e);
		}
		
		try{
			PROGRAMME_MAX_DURATION=Integer.parseInt(systemProperties.getPropertyVal("epg.max.duration"));
		}catch(Exception e){
			log.error(e);
		}
		
		
		SAXReader reader = new SAXReader();

		// 隐蔽dtd验证器，不对xml文件进行dtd验证
		reader.setValidation(false);
		reader.setEntityResolver(new EntityResolver() {
			public InputSource resolveEntity(String publicId, String systemId)
					throws SAXException, IOException {
				return new InputSource(new StringBufferInputStream(""));
			}

		});
		// ///////////////////////////////////////////
       
        
//		InputStreamReader isr = new InputStreamReader(xmlstream);
//		BufferedReader br = new BufferedReader(isr);
//		try {
//			String tempString;
//			StringBuffer sb = new StringBuffer();
//			while ((tempString = br.readLine())!=null) {
//					sb.append(tempString);
//			}
//			System.out.println(sb.toString());
//		} finally {
//			isr.close();
//			br.close();
//		}
        
		Document document = reader.read(xmlstream);

		Element root = document.getRootElement();

		Date stopTimeTemp = null;
		Element element =null;
		log.info("language is:"+language);
		for (Iterator it = root.elementIterator(); it.hasNext();) {
			element = (Element) it.next();
			if(language.equalsIgnoreCase(element.attributeValue("lang"))){
				break;
			}else{
				element=null;
			}
			
		}
		if(element==null){
			errorFlag = true;
			errorCode = "epg.parse.language.no.support";
			return;
		}else{
			root = element;
			for (Iterator it = root.elementIterator(); it.hasNext();) {
				element = (Element) it.next();
				if (channelCode==null&&"channel".equalsIgnoreCase(element.getName())) {
					channelCode = element.attributeValue("id");
					if(channelCode==null){
						errorFlag = true;
						errorCode = "epg.parse.error";
						return;
					}
					channelCode=channelCode.trim();
					//lastProgramEndTime=epgService.getLastProgramEndTime(channelCode);
				}
				
				if ("programme".equalsIgnoreCase(element.getName())) {
					String startTime = element.attributeValue("start");
					String stopTime = element.attributeValue("stop");
					// String channelCode = element.attributeValue("channel");
					Date _startTime=null;
					Date _stopTime=null;
					try {
						_startTime = DateTimeUtils.StringToDate(startTime
								.substring(0, 14), "yyyyMMddHHmmss");
					} catch (Exception e) {
						log.error("EPG time format error,startTime:" + startTime);
						errorFlag = true;
						errorCode = "program.time.format.error";
						errorTime=startTime;
						return;
					}
					
					try {
						_stopTime = DateTimeUtils.StringToDate(stopTime.substring(
								0, 14), "yyyyMMddHHmmss");
					} catch (Exception e) {
						log.error("EPG time format error,stopTime:"+ stopTime);
						errorFlag = true;
						errorCode = "program.time.format.error";
						errorTime=stopTime;
						return;
					}
					/**
					 * 如果节目的起止时间为空，返回错误
					 */
					if (_startTime == null || _stopTime == null) {
						errorFlag = true;
						errorCode = "program.time.format.error";
						return;
					}
					
					/**
					 * 如果导入节目开始时间>=节目的结束时间，返回错误
					 */
					if (_startTime.getTime() >= _stopTime.getTime()) {
						errorFlag = true;
						errorCode = "program.starttime.after.endtime.error";
						errorTime=stopTime;
						return;
					}
					
					if (stopTimeTemp == null) {
						
						Date now = new Date(new Date().getTime() + EPG_OFFSET_TIME * 60 * 1000);
						/**
						 * 如果节目开始时间在当前时间+EPG_OFFSET_TIME时间之前，不导入
						 */
						if (_startTime.getTime() < now.getTime()) {
							/*errorFlag = true;
						errorCode = "program.starttime.before.now";
						return;*/
							
							continue;
						}else{
							programStartTime=_startTime;
						}
					} else {
						/**
						 * 如果节目开始时间小于上个节目的结束时间，返回错误
						 */
						if (_startTime.getTime() < stopTimeTemp.getTime()) {
							errorFlag = true;
							errorCode = "program.starttime.before.last.error";
							errorTime=startTime;
							return;
						}
					}
					
					/**
					 * 节目时长不能小于PROGRAMME_MIN_DURATION
					 */
					if((_stopTime.getTime()-_startTime.getTime())<PROGRAMME_MIN_DURATION* 60 * 1000){
						errorFlag = true;
						errorCode = "program.duration.less.than.mintime";
						errorTime=stopTime;
						return;
					}
					
					/**
					 * 节目时长不能大于PROGRAMME_MAX_DURATION
					 */
					if((_stopTime.getTime()-_startTime.getTime())>PROGRAMME_MAX_DURATION* 60 * 1000){
						errorFlag = true;
						errorCode = "program.duration.beyond.maxtime";
						errorTime=stopTime;
						return;
					}
					
					TvContentInfo tvContent = new TvContentInfo();
					tvContent.setContentId(channelCode + "_"
							+ startTime.substring(0, 14));
					tvContent.setChannelCode(channelCode);
					tvContent.setStartTime(_startTime);
					tvContent.setStartDayOfWeek(DateTimeUtils
							.getDayOfWeek(_startTime));
					tvContent.setEndTime(_stopTime);
					tvContent
					.setEndDayOfWeek(DateTimeUtils.getDayOfWeek(_stopTime));
					tvContent.setDuration(new Long(
							(_stopTime.getTime() - _startTime.getTime())
							/ (1000 * 60)).intValue());
					
					List elementList = element.elements();
					for (int i = 0; i < elementList.size(); i++) {
						Element _element = (Element) elementList.get(i);
//						String lang = _element.attributeValue("lang");
//					if ("zh_CN".equalsIgnoreCase(lang)) {
						if ("title".equalsIgnoreCase(_element.getName())) {
							String title = _element.getText();
							if(title!=null&&title.trim().length()>50){
								errorFlag = true;
								errorCode = "program.title.over.max.length";
								return;
							}
							if(title!=null)
								tvContent.setTitle(title.trim());
						}
						if ("sub-title".equalsIgnoreCase(_element.getName())) {
							String sub_title = _element.getText();
							if(sub_title!=null&&sub_title.trim().length()>50){
								errorFlag = true;
								errorCode = "program.subtitle.over.max.length";
								return;
							}
							if(sub_title!=null)
								tvContent.setSubtitle(sub_title.trim());
						}
						if ("desc".equalsIgnoreCase(_element.getName())) {
							String desc = _element.getText();
							tvContent.setDescription(desc);
						}
						if ("category".equalsIgnoreCase(_element.getName())) {
							String category = _element.getText();
							if(category!=null&&category.trim().length()>64){
								errorFlag = true;
								errorCode = "program.category.over.max.length";
								return;
							}
							if(category!=null){
								tvContent.setCategory(category.trim());
								setContentCategory(category.trim(), tvContent);
							}
						}
//					}
						
						/*if("en".equalsIgnoreCase(lang)){
						if ("category".equalsIgnoreCase(_element.getName())) {
							String category = _element.getText();
							
							tvContent.setCategory(category);
							setContentCategory(category, tvContent);
						}
					}*/
					}
					tvContent.setResistDate(new Date());
					tvContent.setEditDate(new Date());
					tvContent.setCreationDate(new Date());
					tvContent.setStatus(1);
					tvContentList.add(tvContent);
					
					TvContentStatus contentStatus = new TvContentStatus();
					contentStatus.setContentId(channelCode + "_"
							+ startTime.substring(0, 14));
					contentStatus.setIsValid(1);
					contentStatus.setLastUpdateTime(new Date());
					tvContentStatusList.add(contentStatus);
					
					stopTimeTemp = _stopTime;
				}
			}
		}
	}
	
	
	private void setContentCategory(String category,TvContentInfo tvContent){
		tvContent.setCategorySf(0);
		tvContent.setCategoryHorror(0);
		tvContent.setCategoryAction(0);
		tvContent.setCategorySuspense(0);
		tvContent.setCategoryComedy(0);
		tvContent.setCategoryLove(0);
		tvContent.setCategoryPeriod(0);
		tvContent.setCategoryNews(0);
		tvContent.setCategorySports(0);
		tvContent.setCategoryDrama(0);
		tvContent.setCategoryVariety(0);
		tvContent.setCategoryCook(0);
		tvContent.setCategoryQuiz(0);
		tvContent.setCategoryAnimation(0);
		tvContent.setCategoryMusic(0);
		tvContent.setCategoryKids(0);
		tvContent.setCategoryKnowledge(0);
		tvContent.setCategoryNewsComments(0);
		tvContent.setCategoryDocumentary(0);
		tvContent.setCategoryFinancial(0);
		tvContent.setCategoryEducation(0);
		tvContent.setCategoryForeignLanguage(0);
		tvContent.setCategoryEntertainment(0);
		tvContent.setCategorySeries(0);
		tvContent.setCategoryMovies(0);
		tvContent.setCategoryScience(0);
		tvContent.setCategoryLegal(0);
		tvContent.setCategoryMilitary(0);
		tvContent.setCategoryElderly(0);
		tvContent.setCategoryChildren(0);
		tvContent.setCategoryEnvironmental(0);
		tvContent.setCategorySocial(0);
		tvContent.setCategoryFashion(0);
		tvContent.setCategoryWeather(0);
		tvContent.setCategoryAdvertising(0);
		tvContent.setCategoryGangster(0);
		tvContent.setCategoryDisaster(0);
		tvContent.setCategoryEthics(0);
		tvContent.setCategoryBiography(0);
		tvContent.setCategoryMartial(0);
		tvContent.setCategoryWar(0);
		tvContent.setCategoryPolitical(0);
		tvContent.setCategoryDetective(0);
		tvContent.setCategoryLegendary(0);
		tvContent.setCategoryFantastic(0);
		tvContent.setCategoryOther(0);
		
		if("Sf".equalsIgnoreCase(category)){
			tvContent.setCategorySf(1);
		}
		else if("Horror".equalsIgnoreCase(category)){
			tvContent.setCategoryHorror(1);
		}
		else if("Action".equalsIgnoreCase(category)){
			tvContent.setCategoryAction(1);
		}
		else if("Suspense".equalsIgnoreCase(category)){
			tvContent.setCategorySuspense(1);
		}
		else if("Comedy".equalsIgnoreCase(category)){
			tvContent.setCategoryComedy(1);
		}
		else if("Love".equalsIgnoreCase(category)){
			tvContent.setCategoryLove(1);
		}
		else if("Period".equalsIgnoreCase(category)){
			tvContent.setCategoryPeriod(1);
		}
		else if("News".equalsIgnoreCase(category)){
			tvContent.setCategoryNews(1);
		}
		else if("Sports".equalsIgnoreCase(category)){
			tvContent.setCategorySports(1);
		}
		else if("Drama".equalsIgnoreCase(category)){
			tvContent.setCategoryDrama(1);
		}
		else if("Variety".equalsIgnoreCase(category)){
			tvContent.setCategoryVariety(1);
		}
		else if("Cook".equalsIgnoreCase(category)){
			tvContent.setCategoryCook(1);
		}
		else if("Quiz".equalsIgnoreCase(category)){
			tvContent.setCategoryQuiz(1);
		}
		else if("Animation".equalsIgnoreCase(category)){
			tvContent.setCategoryAnimation(1);
		}
		else if("Music".equalsIgnoreCase(category)){
			tvContent.setCategoryMusic(1);
		}
		else if("Kids".equalsIgnoreCase(category)){
			tvContent.setCategoryKids(1);
		}
		else if("Knowledge".equalsIgnoreCase(category)){
			tvContent.setCategoryKnowledge(1);
		}
		else if("News_comments".equalsIgnoreCase(category)){
			tvContent.setCategoryNewsComments(1);
		}
		else if("Documentary".equalsIgnoreCase(category)){
			tvContent.setCategoryDocumentary(1);
		}
		else if("Financial".equalsIgnoreCase(category)){
			tvContent.setCategoryFinancial(1);
		}
		else if("Education".equalsIgnoreCase(category)){
			tvContent.setCategoryEducation(1);
		}
		else if("Foreign_lang".equalsIgnoreCase(category)){
			tvContent.setCategoryForeignLanguage(1);
		}
		else if("Entertainment".equalsIgnoreCase(category)){
			tvContent.setCategoryEntertainment(1);
		}
		else if("Series".equalsIgnoreCase(category)){
			tvContent.setCategorySeries(1);
		}
		else if("Movies".equalsIgnoreCase(category)){
			tvContent.setCategoryMovies(1);
		}
		else if("Science".equalsIgnoreCase(category)){
			tvContent.setCategoryScience(1);
		}
		else if("Legal".equalsIgnoreCase(category)){
			tvContent.setCategoryLegal(1);
		}
		else if("Military".equalsIgnoreCase(category)){
			tvContent.setCategoryMilitary(1);
		}
		else if("Women".equalsIgnoreCase(category)){
			tvContent.setCategoryWomen(1);
		}
		else if("Elderly".equalsIgnoreCase(category)){
			tvContent.setCategoryElderly(1);
		}
		else if("Children".equalsIgnoreCase(category)){
			tvContent.setCategoryChildren(1);
		}
		else if("Environmental".equalsIgnoreCase(category)){
			tvContent.setCategoryEnvironmental(1);
		}
		else if("Social".equalsIgnoreCase(category)){
			tvContent.setCategorySocial(1);
		}
		else if("Fashion".equalsIgnoreCase(category)){
			tvContent.setCategoryFashion(1);
		}
		else if("Weather".equalsIgnoreCase(category)){
			tvContent.setCategoryWeather(1);
		}
		else if("Advertising".equalsIgnoreCase(category)){
			tvContent.setCategoryAdvertising(1);
		}
		else if("Gangster".equalsIgnoreCase(category)){
			tvContent.setCategoryGangster(1);
		}
		else if("Disaster".equalsIgnoreCase(category)){
			tvContent.setCategoryDisaster(1);
		}
		else if("Ethics".equalsIgnoreCase(category)){
			tvContent.setCategoryEthics(1);
		}
		else if("Biography".equalsIgnoreCase(category)){
			tvContent.setCategoryBiography(1);
		}
		else if("Martial".equalsIgnoreCase(category)){
			tvContent.setCategoryMartial(1);
		}
		else if("War".equalsIgnoreCase(category)){
			tvContent.setCategoryWar(1);
		}
		else if("Political".equalsIgnoreCase(category)){
			tvContent.setCategoryPolitical(1);
		}
		else if("Detective".equalsIgnoreCase(category)){
			tvContent.setCategoryDetective(1);
		}
		else if("Legendary".equalsIgnoreCase(category)){
			tvContent.setCategoryLegendary(1);
		}
		else if("Fantastic".equalsIgnoreCase(category)){
			tvContent.setCategoryFantastic(1);
		}
		else{
			tvContent.setCategoryOther(1);
		}
	}

	public String getChannelCode() {
		return channelCode;
	}

	public void setChannelCode(String channelCode) {
		this.channelCode = channelCode;
	}

	public List<TvContentInfo> getTvContentList() {
		return tvContentList;
	}

	public void setTvContentList(List<TvContentInfo> tvContentList) {
		this.tvContentList = tvContentList;
	}

	public List<TvContentStatus> getTvContentStatusList() {
		return tvContentStatusList;
	}

	public void setTvContentStatusList(List<TvContentStatus> tvContentStatusList) {
		this.tvContentStatusList = tvContentStatusList;
	}

	public boolean isErrorFlag() {
		return errorFlag;
	}

	public void setErrorFlag(boolean errorFlag) {
		this.errorFlag = errorFlag;
	}

	public String getErrorCode() {
		return errorCode;
	}

	public void setErrorCode(String errorCode) {
		this.errorCode = errorCode;
	}

	public Date getProgramStartTime() {
		return programStartTime;
	}

	public void setProgramStartTime(Date programStartTime) {
		this.programStartTime = programStartTime;
	}

	public String getErrorTime() {
		return errorTime;
	}

	public void setErrorTime(String errorTime) {
		this.errorTime = errorTime;
	}

}
